package com.seu.me.thread.day2.conn011;

/**
 * 第1种，在方法调用上加了同步，虽然线程安全了，但是每次都要同步，会影响性能，毕竟99%的情况下是不需要同步的，
 * 第2种，在getInstance中做了两次null检查，确保了只有第一次调用单例的时候才会做同步，这样也是线程安全的，
 * 同时避免了每次都同步的性能损耗
 * <p>
 * Created by feihu.Mr on 2017/11/19.
 */
public class DubbleSingleton {

    private static DubbleSingleton ds;

    private DubbleSingleton() {
    }

    //方法1：在getInstance方法上加同步
    public static synchronized DubbleSingleton getInstance() {
        if (ds == null) {
            ds = new DubbleSingleton();
        }
        return ds;
    }

    //方法2：双重检查锁定
    public static DubbleSingleton getDs() {
        if (ds == null) {
            try {
                //模拟初始化对象的准备时间...
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (DubbleSingleton.class) {
                if (ds == null) {
                    ds = new DubbleSingleton();
                }
            }
        }
        return ds;
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        }, "t2");
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        }, "t3");

        t1.start();
        t2.start();
        t3.start();
    }

}
